﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Nirvana
{
    public sealed class AssetBundleItem
    {
        private static Logger logger = LogSystem.GetLogger("AssetBundleItem");
        private float retainTime;
        private float releaseTime;
        private int refCount;
        private string assetPath;
        public string AssetPath
        {
            get { return this.assetPath; }
        }

        public float RetainTime
        {
            get { return this.retainTime; }
        }
        public string error { get; set; }
        public AssetBundle assetbundle;
        public AssetBundleItem[] abItems;
        public WaitLoadAssetBundleAsync waitBundleYield;
        public AssetBundleItem(string path = "")
        {
            this.assetPath = path;  
        }

        public AssetBundleItem(AssetBundle ab, string path = "")
        {
            this.assetbundle = ab;
            this.assetPath = path;
        }

        public AssetBundleItem(WaitLoadAssetBundleAsync waitab, string path = "")
        {
            this.assetPath = path;
            this.waitBundleYield = waitab;
        }

        public int GetReferenceCount()
        {
            return this.refCount;
        }


        public bool GetAssetBundle()
        {
            if (this.waitBundleYield == null) return false;
            if (!this.waitBundleYield.keepWaiting)
            {
                if (this.waitBundleYield.Error != null) this.error = this.waitBundleYield.Error;
                else this.assetbundle = this.waitBundleYield.AssetBundle;

                return true;
            }
            return false;
        }


        public void Retain()
        {
            this.refCount++;
            this.retainTime = Time.time;
            if (LogSystem.IsLogAct(LogActType.AssetBundleReferenceCount))
            {
                logger.LogInfo(string.Format("Retain {0} {1}", this.assetPath, this.refCount));
            }
        }

        public void Release()
        {
            if(this.refCount >0&& --this.refCount <= 0)
            {
                this.releaseTime = Time.time;
            }
            if (LogSystem.IsLogAct(LogActType.AssetBundleReferenceCount))
            {
                logger.LogInfo(string.Format("Release {0} {1}", this.assetPath, this.refCount));
            }
        }

        public void UnLoad(bool isUnloadAll=false)
        {
            if(this.assetbundle != null)
            {
                this.assetbundle.Unload(isUnloadAll);
                if (LogSystem.IsLogAct(LogActType.UnloadAssetBundle))
                {
                    logger.LogInfo(string.Format("Unload {0}", this.assetPath));
                }
            }

            if(this.abItems != null)
            {
                foreach(var p in this.abItems)
                {
                    if (p != null) p.Release();
                }
            }

        }

        public bool IsUnload()
        {
            if (this.refCount > 0) return false;
            if(Time.time >= this.releaseTime + 1f)
            {
                this.UnLoad(true);
                return true;
            }

            return false;
        }

    }
}

